package com.naiterui.ehp.bp.utils.beans.ser;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.google.common.collect.Lists;
import com.naiterui.ehp.bp.utils.beans.annotation.Url;
import com.naiterui.ehp.bp.utils.lang.ConfigUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

public class UrlFieldSerializer extends StdSerializer<Object> implements ContextualSerializer {
    private static final long serialVersionUID = 95121672334433624L;
    private Url url;

    private UrlFieldSerializer(Url url) {
        this();
        this.url = url;
    }

    @SuppressWarnings("WeakerAccess")
    public UrlFieldSerializer() {
        super(Object.class);
    }

    @Override
    public JsonSerializer<Object> createContextual(SerializerProvider prov, BeanProperty property) {
        Url url = property.getAnnotation(Url.class);
        if (url != null) {
            return new UrlFieldSerializer(url);
        }
        return null;
    }

    @Override
    public void serialize(Object obj, JsonGenerator gen, SerializerProvider provider) throws IOException {
        if (!url.serialize()) {
            return;
        }
        if (Objects.isNull(obj)) {
            return;
        }
        if (obj instanceof String) {
            gen.writeString(this.getUrl((String) obj));
        } else if (obj instanceof List) {
            List<Object> url = Lists.newArrayList();
            List<Object> uriList = (List) obj;
            for (Object uri : uriList) {
                if (uri instanceof String) {
                    url.add(this.getUrl((String) uri));
                } else {
                    url.add(uri);
                }
            }
            gen.writeObject(url);
        }
    }

    private String getUrl(String uri) {
        if (StringUtils.isEmpty(uri)) {
            return uri;
        }
        if (uri.startsWith("http")) {
            return uri;
        }
        String imgHost = ConfigUtil.getString(this.url.config());
        String host = StringUtils.isNotEmpty(this.url.host()) ? this.url.host() : imgHost;
        return UriComponentsBuilder.fromUriString(host + "/" + uri).toUriString();
    }
}